package de.rts.ui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;

import javax.swing.JDesktopPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.UIManager;

import de.rts.components.RailwayMap;
import de.rts.logic.TrainController;
import de.rts.xml.MapLoader;

public class RailwaySimulatorFrame extends JFrame implements ActionListener
{

  /**
   * 
   */
  private static final long serialVersionUID = 1L;
  private JDesktopPane      desktop;
  static Dimension          screenSize       = Toolkit.getDefaultToolkit().getScreenSize();
  static int                inset            = 50;
  static int                appWidth         = screenSize.width - inset * 2, appHeight = screenSize.height - inset * 2;
  private RailwayMapPanel   pane;
  private RailwayMapIFrame  iframe;
  private RailwayLogIFrame  logiframe;
  private JFileChooser      fileChooser;
  private RailwayMap        railwayMap;
  private JMenuItem         startItem;
  private TrainController   trainController;
  private String            filePath;
  private JMenuItem         reloadItem;
  private JMenuItem         closeItem;

  public RailwaySimulatorFrame()
  {
    super("Railway System Simulator");
    setBounds(inset, inset, appWidth, appHeight);
    desktop = new JDesktopPane();
    fileChooser = new JFileChooser(".");
    createFrame();
    createLogFrame();
    setJMenuBar(createMenuBar());
    setContentPane(desktop);
    desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
  }

  private void createFrame()
  {
    iframe = new RailwayMapIFrame();
    iframe.setBackground(Color.WHITE);
    iframe.setDefaultCloseOperation(JInternalFrame.DISPOSE_ON_CLOSE);
    iframe.setVisible(true);
    desktop.add(iframe);
    try
    {
      iframe.setSelected(true);
    }
    catch (java.beans.PropertyVetoException e)
    {
    }
  }

  private void createLogFrame()
  {
    logiframe = new RailwayLogIFrame();
    logiframe.setVisible(true);
    desktop.add(logiframe);
  }

  protected JMenuBar createMenuBar()
  {
    JMenuBar menuBar = new JMenuBar();

    JMenu menu = new JMenu("File");
    menu.setMnemonic(KeyEvent.VK_D);
    menuBar.add(menu);

    JMenuItem loadItem = new JMenuItem("Load Map");
    loadItem.setMnemonic(KeyEvent.VK_L);
    loadItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, ActionEvent.ALT_MASK));
    loadItem.setActionCommand("load");
    loadItem.addActionListener(this);
    menu.add(loadItem);

    reloadItem = new JMenuItem("Reload Map");
    reloadItem.setMnemonic(KeyEvent.VK_R);
    reloadItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.ALT_MASK));
    reloadItem.setActionCommand("reload");
    reloadItem.addActionListener(this);
    reloadItem.setEnabled(false);
    menu.add(reloadItem);

    startItem = new JMenuItem("Start");
    startItem.setMnemonic(KeyEvent.VK_S);
    startItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.ALT_MASK));
    startItem.setActionCommand("start");
    startItem.addActionListener(this);
    startItem.setEnabled(false);
    menu.add(startItem);

    closeItem = new JMenuItem("Close");
    closeItem.setMnemonic(KeyEvent.VK_C);
    closeItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.ALT_MASK));
    closeItem.setActionCommand("close");
    closeItem.addActionListener(this);
    closeItem.setEnabled(false);
    menu.add(closeItem);

    JMenuItem quitItem = new JMenuItem("Quit");
    quitItem.setMnemonic(KeyEvent.VK_Q);
    quitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.ALT_MASK));
    quitItem.setActionCommand("quit");
    quitItem.addActionListener(this);
    menu.add(quitItem);

    return menuBar;
  }

  public void actionPerformed(ActionEvent e)
  {
    if (e.getActionCommand().equals("load"))
    {
      fileChooser.setDialogTitle("Select XML Map");
      int val = fileChooser.showOpenDialog(this);
      if (val == JFileChooser.APPROVE_OPTION)
      {
        File file = fileChooser.getSelectedFile();
        if (file != null && !file.getAbsolutePath().endsWith(".xml"))
        {
          showErrorMessage("No XML file selected!", "Invalid File", JOptionPane.ERROR_MESSAGE);
          return;
        }
        filePath = file.getAbsolutePath();
        railwayMap = new MapLoader(filePath).loadMap();
        startItem.setEnabled(true);
        reloadItem.setEnabled(true);
        closeItem.setEnabled(true);
      }
      else if (val == JFileChooser.CANCEL_OPTION) return;
      if (pane == null)
      {
        pane = new RailwayMapPanel(railwayMap);
        iframe.setMapContent(pane);
      }
    }
    else if (e.getActionCommand().equals("quit"))
      System.exit(0);
    else if (e.getActionCommand().equals("close"))
    {
      logiframe.resetLog();
      iframe.dispose();
      createFrame();
      trainController = null;
      pane = null;
      startItem.setEnabled(false);
      reloadItem.setEnabled(false);
      closeItem.setEnabled(false);
    }
    else if (e.getActionCommand().equals("start"))
    {
      if (trainController == null) trainController = new TrainController(pane, railwayMap, logiframe);
    }
    else if (e.getActionCommand().equals("reload"))
    {
      logiframe.resetLog();
      railwayMap = new MapLoader(filePath).loadMap();
      pane = new RailwayMapPanel(railwayMap);
      iframe.removePanelContent(pane);
      trainController = null;
    }
  }

  private void showErrorMessage(String message, String title, int severity)
  {
    JOptionPane.showMessageDialog(this.getParent(), message, title, severity);
  }

  public static void main(String[] args)
  {
    try
    {
      UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    }
    catch (Exception evt)
    {
    }
    javax.swing.SwingUtilities.invokeLater(new Runnable()
    {
      public void run()
      {
        RailwaySimulatorFrame frame = new RailwaySimulatorFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
      }
    });
  }
}
